import 'dart:io';
import 'package:path/path.dart' as path;


/// 快速判断一个文件夹是否为空
/// 返回 true 表示为空，false 表示非空
Future<bool> isDirectoryEmpty(Directory dir) async {
  try {
    // 使用 list() 并设置 `followLinks: false` 和 `recursive: false`
    // 关键：使用 `take(1)` 来只获取第一个条目，避免遍历整个目录
    final stream = dir.list(followLinks: false);
    return stream.isEmpty;
  } catch (e) {
    // 权限问题等，可根据需要处理
    print('检查目录失败: $e');
    return false; // 或抛出异常
  }
}


// 虚拟文件系统，用户可以新建虚拟文件夹，在文件夹里面放置文件夹/文件，不容许新建文件
// 遇到重名文件/夹 需要提示用户改名（改的是虚拟文件/夹名称，磁盘上的不影响）或者取消选择
class VirtualFileEntity {
  String name;
  String path; // 虚拟绝对路径，如 /a.txt
  File file;
  bool isFolder;
  List<VirtualFile> children = [];
}

class VirtualFileSystem { 
  final VirtualFileEntity root;

  VirtualFileSystem() : root = VirtualFileEntity(name: 'root', path: '/', file: null, isFolder: true);

  /// 根据虚拟路径查询文件/文件夹
  /// 路径示例: `/`, `/docs`, `/docs/a.txt`
  VirtualFileEntity? queryFileEntity(String path) {
    if (path == '/' || path.isEmpty) return root;

    // 确保路径以 / 开头
    if (!path.startsWith('/')) {
      path = '/$path';
    }

    final parts = path.split('/').where((p) => p.isNotEmpty).toList();
    VirtualFileEntity? current = root;

    for (final part in parts) {
      final child = current?.children.firstWhereOrNull((e) => e.name == part);
      if (child == null) return null;
      current = child;
    }

    return current;
  }
  
  /// 将一个虚拟文件/文件夹 添加到目标目录
  /// [entity] 要添加的实体（可以是文件或文件夹）
  /// [targetDirPath] 目标目录的虚拟路径（必须是文件夹）
  /// 
  /// 返回值：
  ///   - 成功：返回添加后的实体（路径已更新）
  ///   - 失败（重名）：抛出 [StateError]，消息中包含冲突名称
  ///
  /// 调用者应捕获异常并提示用户改名或取消
  VirtualFileEntity addFileEntity(VirtualFileEntity entity, String targetDirPath) {
    final targetDir = queryFileEntity(targetDirPath);

    if (targetDir == null) {
      throw ArgumentError('目标目录不存在: $targetDirPath');
    }

    if (!targetDir.isFolder) {
      throw ArgumentError('目标路径不是文件夹: $targetDirPath');
    }

    // 检查目标目录下是否已有同名项
    final existing = targetDir.children.firstWhereOrNull((e) => e.name == entity.name);
    if (existing != null) {
      throw StateError('重名冲突: 目录中已存在名为 "${entity.name}" 的文件/文件夹。');
    }
    // 添加到目标目录
    targetDir.children.add(entity);
    return newEntity;
  }

  /// 删除指定路径的文件/文件夹
  /// 返回是否删除成功
  bool delFileEntity(String path) {
    if (path == '/' || path == root.path) {
      // 不允许删除根目录
      return false;
    }
    // 找到父目录
    final parentPath = _getParentPath(path);
    final parent = queryFileEntity(parentPath);
    if (parent == null) return false;

    // 从父目录中移除
    return parent.children.removeWhere(entity);
  }

/// 从 List<html.File> 构建一个虚拟文件夹实体
  /// [files]：用户选择的文件列表（来自 input.webkitdirectory）
  /// [folderName]：根虚拟文件夹的名称（如 "my-project"）
  /// [targetParentPath]：该文件夹将被添加到的父路径（用于生成最终 path）
  ///
  /// 返回：一个代表所选文件夹的 VirtualFileEntity（isFolder = true）
  VirtualFileEntity buildFromWebFiles(
    List<html.File> files,
    String folderName,
    String targetParentPath,
  ) {
    // 1. 确保 targetParentPath 以 / 结尾
    final parentPath = targetParentPath.endsWith('/') ? targetParentPath : '$targetParentPath/';

    // 2. 根虚拟文件夹的完整路径
    final rootFolderPath = '$parentPath$folderName/';

    // 3. 创建根文件夹
    final rootFolder = VirtualFileEntity(
      name: folderName,
      path: rootFolderPath,
      file: null,
      isFolder: true,
    );

    // 4. 按路径层级构建树
    for (final webFile in files) {
      final relativePath = webFile.webkitRelativePath;
      if (relativePath.isEmpty) continue;

      _addFileToVirtualEntity(rootFolder, relativePath, webFile);
    }

    return rootFolder;
  }

/// 将一个 web 文件添加到虚拟文件夹中，按路径自动创建中间目录
  void _addFileToVirtualEntity(
    VirtualFileEntity root,
    String relativePath, // 如: src/utils.js 或 assets/images/bg.png
    html.File webFile,
  ) {
    final parts = relativePath.split('/');
    final fileName = parts.last;
    final dirParts = parts.sublist(0, parts.length - 1); // 中间目录

    VirtualFileEntity current = root;

    // 1. 遍历目录部分，创建中间文件夹
    for (final dirName in dirParts) {
      final dirPath = '${current.path}$dirName/';
      final existingDir = current.children.firstWhereOrNull((e) => e.name == dirName && e.isFolder);

      if (existingDir != null) {
        current = existingDir;
      } else {
        final newDir = VirtualFileEntity(
          name: dirName,
          path: dirPath,
          file: null,
          isFolder: true,
        );
        current.children.add(newDir);
        current = newDir;
      }
    }

    // 2. 添加文件
    final filePath = '${current.path}$fileName';
    final virtualFile = VirtualFileEntity(
      name: fileName,
      path: filePath,
      file: _createDartIoFileFromWebFile(webFile), // 关键：转换
      isFolder: false,
    );

    // 检查重名（由调用者处理冲突）
    if (current.children.any((e) => e.name == fileName && !e.isFolder)) {
      // 注意：这里不抛异常，由 addFileEntity 统一处理冲突
      // 我们只是构建结构，不负责路径唯一性
    }

    current.children.add(virtualFile);
  }

io.File _createDartIoFileFromWebFile(html.File webFile) {
    // 在 Web 上，无法直接创建真实的 io.File
    // 我们可以将内容读取到内存，然后用一个内存文件系统或自定义类
    // 为了兼容你的模型，这里演示如何读取内容

    final completer = Completer<Uint8List>();
    final reader = html.FileReader();
    reader.readAsArrayBuffer(webFile);
    reader.onLoad.listen((_) {
      final buffer = reader.result as ByteBuffer;
      completer.complete(buffer.asUint8List());
    });
    reader.onError.listen((error) => completer.completeError(error));

    // 注意：这里是同步返回，实际是异步读取
    // 你需要重构模型，使用 Future<Uint8List> 或先异步读取所有内容
    // 以下为简化演示，返回 null
    // 强烈建议：先异步读取所有文件内容，再构建 VirtualFileEntity

    throw UnimplementedError(
      '在 Web 上，你需要先异步读取所有文件内容，'
      '然后使用一个自定义类（如 MemoryBackedFile）来持有 bytes，'
      '而不是直接使用 dart:io.File'
    );
  }

}
